package com.jysz.certificate.web.action.mf;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
 
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.jysz.certificate.action.AbstractBaseAction;
import com.jysz.certificate.persistence.enums.mf.BillStatus;
import com.jysz.certificate.persistence.model.cm.Certification;
import com.jysz.certificate.persistence.model.mf.Bill;
import com.jysz.certificate.persistence.model.mf.BillApply;
import com.jysz.certificate.persistence.model.mf.BillOption;
import com.jysz.certificate.persistence.model.system.Shop;
import com.jysz.certificate.service.mf.BillApplyService;
import com.jysz.certificate.service.mf.BillOptionService;
import com.jysz.certificate.service.mf.BillService;
import com.jysz.certificate.service.system.ShopService;
import com.jysz.certificate.utils.DateUtil;
import com.jysz.certificate.utils.PoiUtils;
import com.jysz.certificate.web.action.Excel.ExcelSheetParser;

/**
 * 发票操作控制类(开票、实收、注销、重开)
 * @author xuxiaolong
 */
@Controller
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Namespace("/mf/core")
public class BillOpenAction extends AbstractBaseAction {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	@Resource
	private BillApplyService applyService;
	@Resource
	private BillService billService;
	@Resource
	private BillOptionService billOptionService;
	@Resource
	private ShopService shopService;
	
	
	private Bill billDTO;
	private Bill bill;
	
	private Date openDateBegin;//开立发票开始时间
	private Date openDateEnd;//开立发票结束时间
	private Date applyDateBegin;//申请开始时间
	private Date applyDateEnd;//申请结束时间
	private Integer status;//状态
	private Long billId;//
	private Long id;//
	private File fileURL;
	private String markShop;
	private String billName;
	private String billNum;
	private String yserNo;
	
	private String billRemark;
	
	
	public String getMarkShop() {
		return markShop;
	}

	public void setMarkShop(String markShop) {
		this.markShop = markShop;
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public File getFileURL() {
		return fileURL;
	}

	public void setFileURL(File fileURL) {
		this.fileURL = fileURL;
	}

	public Long getBillId() {
		return billId;
	}

	public void setBillId(Long billId) {
		this.billId = billId;
	}

	public Bill getBill() {
		return bill;
	}

	public void setBill(Bill bill) {
		this.bill = bill;
	}

	public Integer getStatus() {
		return status;
	}

	public void setStatus(Integer status) {
		this.status = status;
	}

	public Date getOpenDateBegin() {
		return openDateBegin;
	}

	public void setOpenDateBegin(Date openDateBegin) {
		this.openDateBegin = openDateBegin;
	}

	public Date getOpenDateEnd() {
		return openDateEnd;
	}

	public void setOpenDateEnd(Date openDateEnd) {
		this.openDateEnd = openDateEnd;
	}

	public Date getApplyDateBegin() {
		return applyDateBegin;
	}

	public void setApplyDateBegin(Date applyDateBegin) {
		this.applyDateBegin = applyDateBegin;
	}

	public Date getApplyDateEnd() {
		return applyDateEnd;
	}

	public void setApplyDateEnd(Date applyDateEnd) {
		this.applyDateEnd = applyDateEnd;
	}

	public Bill getBillDTO() {
		return billDTO;
	}

	public void setBillDTO(Bill billDTO) {
		this.billDTO = billDTO;
	}
	//提交发票
			@Action("billSubmit")
			public String billSubmit(){
				boolean mon=true;
				bill = billService.find(id);
				bill.setStatus(BillStatus.APPLYED);
				for(int i=0;i<bill.getOptions().size();i++){
					BillOption billOption = bill.getOptions().get(i);
					billOption.setStatus(BillStatus.APPLYED);
					billOptionService.save(billOption);
				}
				billService.save(bill);
				BillApply billApply =bill.getBillApply();
				for(int i=0; i<billApply.getBills().size();i++){
					Bill billui=billApply.getBills().get(i);
					if(billui.getStatus().compareTo(BillStatus.TEMPSAVE) == 0 ){
						mon=false;
					}
				}
				if(mon){
					billApply.setStatus(BillStatus.APPLYED);
					applyService.save(billApply);
				}
				setRedirectUrl("index.do?currentPage="+getCurrentPage(),"billDTO",billDTO);
				setSuccessPopMessage("申请开票成功");
				return SHOW_MSG_PAGE;
			}
	/**  发票查询*/
	@Action("export")
	public String export(){
		Shop shop = null;
		if(StringUtils.isNotBlank(markShop)){
			shop = shopService.findShopByName(markShop);
		}
		if(billDTO == null ){
			billDTO = new Bill();
			billDTO.setShop(shop);
		}else{
			billDTO.setShop(shop);
		}
		Boolean bo = false;
		if(StringUtils.isNotBlank(yserNo)){
			bo = true;
		}
		List<Bill> cfs = billService.exportBills(bo,billDTO, getCurrentPage(), getPageSize(),openDateBegin,openDateEnd,applyDateBegin,applyDateEnd,status);

		
		String[] headers = {"发票号", "发票名", "付款方名称", "应收金额", "实收金额", "申请时间", "开票时间","状态","开票项目说明"};
		String[] columns = {"billNum", "billName", "paymentName", "receivableAmount", "factAmount",
				"@com.jysz.certificate.utils.DateUtil@formatDate(applyDate,'yyyy-MM-dd')","@com.jysz.certificate.utils.DateUtil@formatDate(openDate,'yyyy-MM-dd')", "#cfa.getStatusStr(#cf)","billRemark"};
		HttpServletResponse response = this.getResponse();
	    response.setContentType("octets/stream");
	    response.addHeader("Content-Disposition",
	                "attachment;filename=" + toUtf8Encode("发票") + ".xls");
		OutputStream out = null;
		try {
			
			out = this.getResponse().getOutputStream();
			Map<String, Object> context = new HashMap<String, Object>();
			context.put("cfa", this);
			PoiUtils.exportExcel("发票", headers, columns, cfs, out, null, context,"cf");
		} catch (Exception e) {
			LOG.error("导出发票出错。。。", e);
		}
		
		return null;
	}
	/**  发票查询*/
	@Action(INDEX)
	public String index(){
		Shop shop = null;
		Boolean bo = false;
		if(StringUtils.isNotBlank(markShop)){
			shop = shopService.findShopByName(markShop);
		}
		if(billDTO == null ){
			billDTO = new Bill();
			billDTO.setShop(shop);
		}else{
			billDTO.setShop(shop);
		}
		if(StringUtils.isNotBlank(yserNo)){
			bo = true;
		}
		setPage(billService.findPage(bo,billDTO, getCurrentPage(), getPageSize(),openDateBegin,openDateEnd,applyDateBegin,applyDateEnd,status,getUser()));
		return INDEX;
	}
	public String getStatusStr(Bill cu){
		return cu.getStatus().getName();
	}
	/**
	 * 发票 详情
	 *金融机构
	 * **/
	@Action("editFinancialSelete")
	public String editFinancialSelete(){
		bill = billService.find(id);
	System.out.println(bill.getOptions().size());
		return "editFinancialSelete";
	}
	
	/**
	 *打开发票项目说明页面
	 * **/
	@Action("openUpdateBillRemark")
	public String openUpdateBillRemark(){
		bill = billService.find(id);
		setRedirectUrl("index.do?currentPage=" + getCurrentPage(), "billDTO", billDTO);
		return "updateBillRemark";
	}
	/**
	 * 修改发票项目说明页面
	 * @return
	 */
	@Action("updateBillRemark")
	public String updateBillRemark(){
		bill = billService.find(id);
		bill.setBillRemark(billRemark);
		billService.save(bill);
		setSuccessPopMessage("数据更新成功");
		return SHOW_MSG_PAGE;
	}
	
	/**  开立发票*/
	@Action(ADD)
	public String add(){
		bill = billService.find(billDTO.getId());
		bill.setBillName(billDTO.getBillName());
		bill.setBillNum(billDTO.getBillNum());
		bill.setOpenDate(billDTO.getOpenDate());
		bill.setStatus(BillStatus.OPENED);
		List<BillOption> billOptions = new ArrayList<BillOption>();
		if(bill.getOptions() != null && bill.getOptions().size()>0){
			for(BillOption billOption : bill.getOptions()){
				if(billOption.getStatus().equals(BillStatus.APPLYED)){
					billOption.setStatus(BillStatus.OPENED);
				}
				billOptions.add(billOption);
			}
		}
		bill.setOptions(billOptions);
		billService.save(bill);
		setSuccessPopMessage("发票开立成功");
		return SHOW_MSG_PAGE;
	}
	/**  开立发票页面*/
	@Action("addLoke")
	public String addLoke(){
		bill = billService.find(billId);
		setRedirectUrl("index.do?currentPage=" + getCurrentPage(), "billDTO", billDTO);
		return "openBillAdd";
	}
	/**  批量开票页面*/
	@Action("openImport")
	public String openImport(){
		setRedirectUrl("index.do?currentPage=" + getCurrentPage(), "billDTO", billDTO);
		return "import";
	}
	/** 批量开票*/
	@Action("toImport")
	public String toImport(){
		int minute =0;
		int sum =0;
		List<Bill> billList =new ArrayList<Bill>();
		Boolean mark =true;
		try {
			ExcelSheetParser parser = new ExcelSheetParser(fileURL);
			List<List> datas = parser.getDatasInSheet(0);
//			Boolean mark =true;
//			Map<String, Bill> mapBillName = billService.billMapBillName();
//			Map<String, String> BillNamemap = new HashMap<String, String>();
			Map<String, String> BillNummap = new HashMap<String, String>();
			Map<String, Bill> mapBillNum = billService.billMapBillNum();
			Bill sitakBill = null;
			sum = datas.size()-2;
			for(int i=1;i<datas.size();i++){//显示数据
				List row = datas.get(i);
//				sitakBill = new Bill();
				if(!StringUtils.isNotBlank(String.valueOf(row.get(0)).trim()) || String.valueOf(row.get(0)).equals("null")){
					continue;
				}
					String objValue = String.valueOf(row.get(6));
					String stateString = String.valueOf(row.get(11)).trim();
					
					if(!StringUtils.isNotBlank(objValue) || stateString.equals("null")){
						this.addActionError("第"+(i+1)+"行，第7列,合计金额     数据不能为空\n");
						mark = false;
						continue;
					}
					String aString = String.valueOf(row.get(14));
					System.out.println(aString);
					if(!StringUtils.isNotBlank(String.valueOf(row.get(14)).trim()) || String.valueOf(row.get(14)).equals("null")){
						this.addActionError("第"+(i+1)+"行，第15列,开票项目说明    不能为空\n");
						mark = false;
						continue;
					}
					if(!StringUtils.isNotBlank(String.valueOf(row.get(8)).trim()) || String.valueOf(row.get(8)).equals("null")){
						this.addActionError("第"+(i+1)+"行，第9列,付款方名称     不能为空\n");
						mark = false;
						continue;
					}
					if(stateString.equals("填用"))
						sitakBill = billService.minuteBill(String.valueOf(row.get(8)),Double.parseDouble(objValue),String.valueOf(row.get(14)));
					if(StringUtils.isNotBlank(stateString) && !stateString.equals("null")){
					}else{
						this.addActionError("第"+(i+1)+"行，第11列,数据不能为空\n");
						 mark = false;
						 continue;
					}
					if(null != sitakBill){
							if(StringUtils.isNotBlank(String.valueOf(row.get(2))) && !String.valueOf(row.get(2)).equals("null")){
								 
							}else{
								this.addActionError("第"+(i+1)+"行，第3列,数据不能为空\n");
								 mark = false;
								 continue;
							}
							if(StringUtils.isNotBlank(String.valueOf(row.get(4))) && !String.valueOf(row.get(4)).equals("null")){
								String a = String.valueOf(row.get(4).toString().trim());
								if(mapBillNum.containsKey(String.valueOf(row.get(4).toString().trim()))){
									this.addActionError("第"+(i+1)+"行，第5列,发票号重复, 重复值："+a+"\n");
									 mark = false;
									 continue;
								}else if(BillNummap.containsKey(String.valueOf(row.get(4)))){
									this.addActionError("文件中有重复的发票号，重复发票号为："+String.valueOf(row.get(4))+"\n");
									 mark = false;
									 continue;
								}else{
									BillNummap.put(a, a);
								}
							}else{
								this.addActionError("第"+(i+1)+"行，第5列,数据不能为空\n");
								 mark = false;
								 continue;
							}
							Date date = null;
							if(StringUtils.isNotBlank(String.valueOf(row.get(5))) && !String.valueOf(row.get(5)).equals("null")){
								SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
								try {
									date = sdf.parse(String.valueOf(row.get(5)));
								} catch (Exception e) {
									this.addActionError("第"+(i+1)+"行，第6列,开票时间数据错误\n");
									 mark = false;
									 continue;
								}
							}else{
								this.addActionError("第"+(i+1)+"行，第6列,开票时间    不能为空\n");
								 mark = false;
								 continue;
							}
							if(mark){
								boolean bo=true;
								sitakBill.setBillName(String.valueOf(row.get(2)));
								sitakBill.setBillNum(String.valueOf(row.get(4)));
								System.out.println(String.valueOf(row.get(4)));
								sitakBill.setOpenDate(date);
								sitakBill.setStatus(BillStatus.OPENED);
//								if(billList.size()>0){
//									for(Bill objBill : billList){
//										System.out.println(sitakBill.getPaymentName());
//										System.out.println(objBill.getPaymentName());
//										System.out.println(sitakBill.getReceivableAmount());
//										System.out.println(sitakBill.getReceivableAmount());
//										System.out.println(stateString);
//										if(sitakBill.getPaymentName().equals(objBill.getPaymentName()) && sitakBill.getReceivableAmount()==sitakBill.getReceivableAmount()&&stateString.equals("填用")){
//											this.addActionError("第"+(i+1)+"行，第5列,开票时间数据错误\n");
//											bo = false;
//											mark = false;
//											 break;
//										}
//									}
//								}
								if(bo){
									List<BillOption> billOptions = new ArrayList<BillOption>();
									if(sitakBill.getOptions() != null && sitakBill.getOptions().size()>0){
										for(BillOption billOption : sitakBill.getOptions()){
											if(billOption.getStatus().equals(BillStatus.APPLYED)){
												billOption.setStatus(BillStatus.OPENED);
											}
											billOptions.add(billOption);
										}
									}
									sitakBill.setOptions(billOptions);
									billList.add(sitakBill);
								}
								
							}
				}
				
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			System.out.println("文件没找到 : " + e);  
		} catch (IOException e) {
			this.addActionError("文件不匹配, 请确认导入文件是合格证导入文件\n");
		}
		if(mark){
			for(int i=0; i<billList.size();i++){
				Bill billKey =billList.get(i);
				billService.save(billKey);
				minute += 1;
			}
			setSuccessPopMessage("总共导入发票数："+sum +"   成功开票："+ minute);
			return SHOW_MSG_PAGE;
		}else{
			return "import";
		}
		
		
	}

	/**
	 * 红字发票 链接原发票详情
	 * @author xuxiaolong
	 * **/
	@Action("billDisplay")
	public String billDisplay(){
		
		Bill redBill = billService.find(id);
		if(redBill!=null&&redBill.getOptions()!=null&&redBill.getOptions().size()>0){
			List<Bill> bills=redBill.getOptions().get(0).getBills();
			if(bills!=null){
				for(Bill tmp:bills){
					if(tmp.getId()!=redBill.getId()){
						bill=tmp;
						break;
					}
				}
			}
		}
		if(bill==null)
			return this.editFinancialSelete();
		else
			return "editFinancialSelete";
	}
	
	public int getCheckDate(Date d){
		if(d==null){
			return -1;
		}
		if(DateUtil.isSameYM(d, new Date())){//开票时间是本月
			return 0;
		}
		Date now =new Date();
		Long dLong = d.getTime() / 1000;
		Long nowLong = now.getTime() / 1000;
		if(dLong<nowLong&&!DateUtil.isSameYM(d, now)){//开票时间是当前月之前的月份。不包含当前月
			return 1;
		}
		return -1;
		
	}
	/**
	 * Ajax 效验发票明是否相同
	 * @return
	 */
	@Action("ajaxBillName")
	public String ajaxBillName(){
		Map<String, Bill> map = billService.billMapBillName();
		Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
		if(billName !=null){
			if(map.containsKey(billName)){
				this.setJsonText(gson.toJson(false));
			}else{
				this.setJsonText(gson.toJson(true));
			}
		}
		
		return JSON_PAGE;
	}
	/**
	 * Ajax 效验发票号是否相同
	 * @return
	 */
	@Action("ajaxBillNum")
	public String ajaxBillNum(){
		Map<String, Bill> map = billService.billMapBillNum();
		Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
		if(billName !=null){
			if(map.containsKey(billNum)){
				this.setJsonText(gson.toJson(false));
			}else{
				this.setJsonText(gson.toJson(true));
			}
		}
		return JSON_PAGE;
	}

	public String getBillName() {
		return billName;
	}

	public void setBillName(String billName) {
		this.billName = billName;
	}

	public String getBillNum() {
		return billNum;
	}

	public void setBillNum(String billNum) {
		this.billNum = billNum;
	}

	public String getYserNo() {
		return yserNo;
	}

	public void setYserNo(String yserNo) {
		this.yserNo = yserNo;
	}

	public String getBillRemark() {
		return billRemark;
	}

	public void setBillRemark(String billRemark) {
		this.billRemark = billRemark;
	}
}
